package com.scalar.chiptrack.adaptor.sitime.arrow;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.InventoryLot;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.TestLot;
import com.scalar.chiptrack.adaptor.utils.ParserResult;
import com.scalar.chiptrack.adaptor.utils.Parser;
import com.scalar.chiptrack.adaptor.utils.ParserFactory;
import com.scalar.chiptrack.adaptor.utils.XLSParserImpl;
import com.scalar.chiptrack.adaptor.dao.InventoryLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.adaptor.dao.TestAdaptorDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.operations.release.dao.RelaseDAO;
import com.scalar.chiptrack.operations.release.ReleaseLot;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Date;
import java.io.File;

/**
 * Created by IntelliJ IDEA.
 * User: munugoti
 * Date: 2 Feb, 2010
 * Time: 11:12:21 AM
 */
public class ArrowDataParser extends JobHandler implements AdaptorConstants
{
    private HashMap<String, InventoryLot> m_renoFgDataMap = new HashMap<String, InventoryLot>();
    private HashMap<String, InventoryLot> m_penangFgDataMap = new HashMap<String, InventoryLot>();
    private HashMap<String, TestLot> m_penangTestDataMap = new HashMap<String, TestLot>();

    private Logger m_parserLogger       = null;
    private String m_dataOutputDir      = null;

    public  ArrowDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_ARROW_RENO , LOCATION_TYPE_FINISHED_GOODS );

            if ( m_dataOutputDir != null )
            {
                AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );

                m_parserLogger= AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_ARROW_RENO );

                AdaptorUtils.setLogger( m_parserLogger );
                InventoryLotDAO.setLogger(m_parserLogger);
                TestAdaptorDAO.setLogger( m_parserLogger );
            }
        }
        catch ( Exception se )
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading ARROW output directory details from database, Exception: " + se );
            System.out.println( "ERROR!! ERROR!! ERROR!! Exception while loading ARROW output directory details from database, Exception: " + se );
        }
    }
    public static void main( String args[] ) throws Exception
    {
        try
        {
            new ArrowDataParser().execute();
        }
        catch ( Exception e )
        {
            throw e;
        }
    }
    public void execute() throws Exception
    {
        AdaptorUtils.printHeader( VENDOR_NAME_ARROW_RENO, CONSTANT_PARSER );

        File doneDestDir = new File( m_dataOutputDir + "/done" );
        File dataoutDir  = new File( m_dataOutputDir );

        File[] fileList = dataoutDir.listFiles();

        if ( ( fileList == null ) || (fileList.length <= 3))
        {
            log("No file found in directory: " + dataoutDir);
            System.out.println("No file found in directory: " + dataoutDir );
            throw new ScalarException("No file found in directory: " + dataoutDir+ "----\n\n" );
        }

        ArrayList<File> successFileList = new ArrayList<File>();

        boolean success = false;

        for ( int i = 0; i < fileList.length; i++ )
        {
            if ( fileList[i].isDirectory() == true )
            {
                continue;
            }

            try
            {
                if ( fileList[i].getName().startsWith( ArrowFTPAdaptor.FILE_NAME_RENO_WIP )  || fileList[i].getName().indexOf( ArrowFTPAdaptor.FILE_NAME_RENO_WIP )  != -1)
                {
                     parseRenoFGWipReport( fileList[i].getAbsolutePath() );

                    successFileList.add(fileList[i]);
                }
                if ( fileList[i].getName().startsWith( ArrowFTPAdaptor.FILE_NAME_PENANG_WIP )  || fileList[i].getName().indexOf( ArrowFTPAdaptor.FILE_NAME_PENANG_WIP )  != -1)
                {
                     parsePenangFGWipReport( fileList[i].getAbsolutePath() );

                    successFileList.add(fileList[i]);
                }
                if ( fileList[i].getName().startsWith( ArrowFTPAdaptor.FILE_NAME_SCHEDULE_WIP )  || fileList[i].getName().indexOf( ArrowFTPAdaptor.FILE_NAME_SCHEDULE_WIP )  != -1)
                {
                     parseScheduleFGWipReport( fileList[i].getAbsolutePath() );

                    successFileList.add(fileList[i]);
                }


               success = true;
            }
            catch (Exception e)
            {
                success = false;
                log("Exception while parsing file: " + fileList[i].getAbsolutePath() + "\nException: " + e);
                e.printStackTrace();
                throw e;
            }
        }

       // to save the Finished Goods lot tables
       try
       {
           if ( m_renoFgDataMap.isEmpty() == false )
           {
               log(" Updating Reno Finished Goods Lot Information");
               InventoryLotDAO.saveInventoryLot( null, m_renoFgDataMap.values().iterator(), LOCATION_TYPE_FG, VENDOR_NAME_ARROW_RENO );
               success = true;
           }
           else
           {
               InventoryLotDAO.closeInventoryLot(null, LOCATION_TYPE_FG, VENDOR_NAME_ARROW_RENO );
           }
      }
      catch (ScalarException se)
      {
          success = false;
          se.printStackTrace();
          log("ERROR!! ERROR!! ERROR!! Could not update Finished Goods Lot information into database: " + se);
          throw se;
      }

       try
        {
           // Saving FINAL TEST Information
           if ( m_penangTestDataMap.isEmpty() == false )
            {
                log( " Updating Test Lot Information" );
                TestAdaptorDAO.saveTestLot( null,m_penangTestDataMap.values().iterator(), LOCATION_TYPE_FT, VENDOR_NAME_ARROW_PENANG );
            }
            else
           {
               TestAdaptorDAO.closeTestLot( null, LOCATION_TYPE_FT, VENDOR_NAME_ARROW_PENANG );
           }

           success = true;
        }
        catch ( ScalarException se )
        {
            success = false;
            se.printStackTrace();
            log( "ERROR!! ERROR!! ERROR!! Could not update Test Lot information into database: " + se );
            throw se;
        }
       try
       {
           if ( m_penangFgDataMap.isEmpty() == false )
           {
               log(" Updating Penanng  Finished Goods Lot Information");
               InventoryLotDAO.saveInventoryLot( null, m_penangFgDataMap.values().iterator(), LOCATION_TYPE_FG, VENDOR_NAME_ARROW_PENANG );
               success = true;
           }
           else
           {
               InventoryLotDAO.closeInventoryLot(null, LOCATION_TYPE_FG, VENDOR_NAME_ARROW_PENANG );
           }
      }
      catch (ScalarException se)
      {
          success = false;
          se.printStackTrace();
          log("ERROR!! ERROR!! ERROR!! Could not update Finished Goods Lot information into database: " + se);
          throw se;
      }
        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_ARROW_RENO,true, true, true );
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_ARROW_PENANG,true, true, true );

        // To Close the Drop Out Lots
        AdaptorDAO.closeDropOutLots( VENDOR_NAME_ARROW_RENO );
        AdaptorDAO.closeDropOutLots( VENDOR_NAME_ARROW_PENANG );

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( ArrowFTPAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);
        // transaction 9
        try
        {
            if (success)
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, ArrowFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println("SUCCESSFULLY UPDATED IN THE DATABASE");
            }
        }
        catch (ScalarException se)
        {
            success = false;  //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, ArrowFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log("WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se);
            throw se;
        }

        // Step 10
        // Move the successful files to 'done' directory
        if (success)
        {
            AdaptorUtils.moveFilesToDone( successFileList, doneDestDir);
        }
    }

    private void parseRenoFGWipReport (String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result            = null;

        InventoryLot inventoryLot  = null;
        String partNumber       = null;
        String fabLotNumber     = null;
        int dieQtyIn            = 0;

        try
        {
            File detailWipFile = new File( fileName );
            if ( !detailWipFile.exists() )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            Parser parser = ParserFactory.getXLSParser( detailWipFile );

            ((XLSParserImpl)parser).setHeaderRowIdx(0);
            ((XLSParserImpl)parser).setDataStartRowIdx(1);

            log( "\nFound " + fileName );
            log( "\nParsing the file for FG WIP Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for FG WIP Report..." );

            result = parser.parse();

            while ( result.next() )
            {
                partNumber      = result.getString("Part Number");
                fabLotNumber    = result.getString("Lot Code");

                if ( partNumber != null && partNumber.trim().length() > 0 && fabLotNumber != null && fabLotNumber.trim().length() > 0 )
                {
                    if (partNumber.indexOf("*") != -1 )
                    {
                        partNumber = partNumber.substring(0, partNumber.indexOf("*"));
                    }

                    try
                    {
                        dieQtyIn = result.getInt("Avail") ;
                    }
                    catch(NumberFormatException nfe)
                    {
                        dieQtyIn = 0;
                    }

                    if ( dieQtyIn > 0 )
                    {
                        log("IN FG lotNumber = " + fabLotNumber);
                        inventoryLot = m_renoFgDataMap.get( fabLotNumber + partNumber );

                        if( inventoryLot == null )
                        {
                            inventoryLot = new InventoryLot( VENDOR_NAME_ARROW_RENO,  LOCATION_TYPE_FG);
                            m_renoFgDataMap.put(  fabLotNumber + partNumber , inventoryLot );
                        }
                        int quantity = 0;
                        if (inventoryLot.getQtyIn() != null )
                        {
                            try
                            {
                                quantity = Integer.parseInt(inventoryLot.getQtyIn() );
                            }
                            catch (NumberFormatException nfe)
                            {
                                quantity = 0;
                            }
                            quantity += dieQtyIn;
                        }
                        else
                        {
                            quantity = dieQtyIn;
                        }
                        inventoryLot.setPartNumber( partNumber );
                        inventoryLot.setLotNumber( fabLotNumber );
                        inventoryLot.setFabLotNumber( fabLotNumber );
                        inventoryLot.setQtyIn( quantity+"" );
                        inventoryLot.setStatus(LOT_STATUS_RUNNING);
                        inventoryLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                        inventoryLot.setDateCode( result.getString("Date Code") );
                    }
                }
            }
        }
        catch(Exception e )
        {
            e.printStackTrace();
            throw e;
        }
    }

    private void parsePenangFGWipReport (String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result            = null;

        InventoryLot inventoryLot  = null;
        String partNumber       = null;
        String fabLotNumber     = null;
        int dieQtyIn            = 0;

        try
        {
            File detailWipFile = new File( fileName );
            if ( !detailWipFile.exists() )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            Parser parser = ParserFactory.getXLSParser( detailWipFile, "SiTime Qty - APP0" );

            ((XLSParserImpl)parser).setHeaderRowIdx(0);
            ((XLSParserImpl)parser).setDataStartRowIdx(1);

            log( "\nFound " + fileName );
            log( "\nParsing the file for FG WIP Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for FG WIP Report..." );

            result = parser.parse();

            while ( result.next() )
            {
                partNumber      = result.getString("Part Number");
                fabLotNumber    = result.getString("Lot Code");

                if ( partNumber != null && partNumber.trim().length() > 0 && fabLotNumber != null && fabLotNumber.trim().length() > 0 )
                {
                    if (partNumber.indexOf("*") != -1 )
                    {
                        partNumber = partNumber.substring(0, partNumber.indexOf("*"));
                    }
                    
                    try
                    {
                        dieQtyIn = result.getInt("Avail") ;
                    }
                    catch(NumberFormatException nfe)
                    {
                        dieQtyIn = 0;
                    }

                    if ( dieQtyIn > 0 )
                    {
                        log("IN FG lotNumber = " + fabLotNumber);
                        inventoryLot = m_penangFgDataMap.get( fabLotNumber + partNumber );

                        if( inventoryLot == null )
                        {
                            inventoryLot = new InventoryLot( VENDOR_NAME_ARROW_PENANG,  LOCATION_TYPE_FG);
                            m_penangFgDataMap.put(  fabLotNumber + partNumber , inventoryLot );
                        }
                        int quantity = 0;
                        if (inventoryLot.getQtyIn() != null )
                        {
                            try
                            {
                                quantity = Integer.parseInt(inventoryLot.getQtyIn() );
                            }
                            catch (NumberFormatException nfe)
                            {
                                quantity = 0;
                            }
                            quantity += dieQtyIn;
                        }
                        else
                        {
                            quantity = dieQtyIn;
                        }
                        inventoryLot.setPartNumber( partNumber );
                        inventoryLot.setLotNumber( fabLotNumber );
                        inventoryLot.setFabLotNumber( fabLotNumber );
                        inventoryLot.setQtyIn( quantity+"" );
                        inventoryLot.setStatus(LOT_STATUS_RUNNING);
                        inventoryLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                        inventoryLot.setDateCode( result.getString("Date Code") );
                    }
                }
            }
        }
        catch(Exception e )
        {
            e.printStackTrace();
            throw e;
        }
    }

    private void parseScheduleFGWipReport (String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result            = null;

        InventoryLot inventoryLot  = null;
        String testReleaseNo       = null;
        String orderStatus         = null;
        ReleaseLot  releaseLot     = null;
        TestLot testLot            = null;

        try
        {
            File detailWipFile = new File( fileName );
            if ( !detailWipFile.exists() )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            Parser parser = ParserFactory.getXLSParser( detailWipFile );

            ((XLSParserImpl)parser).setHeaderRowIdx(0);
            ((XLSParserImpl)parser).setDataStartRowIdx(1);

            log( "\nFound " + fileName );
            log( "\nParsing the file for Arrow Schedule WIP Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Arrow Schedule WIP Report..." );

            result = parser.parse();

            while ( result.next() )
            {
                testReleaseNo      = result.getString("Job #");
                orderStatus        = result.getString("Order Status");

                if ( orderStatus != null && orderStatus.trim().length() > 0 && testReleaseNo != null && testReleaseNo.trim().length() > 0
                    && ("In progress".equalsIgnoreCase(orderStatus) || "Order entry".equalsIgnoreCase( orderStatus ) || "Order release".equalsIgnoreCase( orderStatus ) ) )
                {
                    int testReleaseID = RelaseDAO.getTestReleaseId( testReleaseNo);

                    if ( testReleaseID > 0 )
                    {
                        ArrayList<ReleaseLot> releaseLotList = RelaseDAO.getTestReleaseLotsInfo(testReleaseID);
                        if (releaseLotList != null && releaseLotList.size() > 0 )
                        {
                            for (int i=0; i <releaseLotList.size(); i++ )
                            {
                                releaseLot = releaseLotList.get(i);

                                testLot = m_penangTestDataMap.get( releaseLot.getLotNumber() + releaseLot.getPartNumber() );

                                if( testLot == null )
                                {
                                    testLot = new TestLot( VENDOR_NAME_ARROW_PENANG,  LOCATION_TYPE_FT );
                                    m_penangTestDataMap.put(  releaseLot.getLotNumber() + releaseLot.getPartNumber() , testLot );
                                }
                                int quantity = 0;
                                if (testLot.getQtyIn() != null )
                                {
                                    try
                                    {
                                        quantity = Integer.parseInt(testLot.getQtyIn() );
                                    }
                                    catch (NumberFormatException nfe)
                                    {
                                        quantity = 0;
                                    }
                                    quantity += releaseLot.getQtyIn();
                                }
                                else
                                {
                                    quantity = releaseLot.getQtyIn();
                                }
                                testLot.setPartNumber( releaseLot.getPartNumber() );
                                testLot.setLotNumber( releaseLot.getLotNumber() );
                                testLot.setFabLotNumber( releaseLot.getLotNumber() );
                                testLot.setQtyIn( quantity+"" );
                                testLot.setStatus(LOT_STATUS_RUNNING);
                                testLot.setCategory( LOT_CATEGORY_TYPE_PROD );
                            }
                        }
                    }
                }
            }
        }
        catch(Exception e )
        {
            e.printStackTrace();
            throw e;
        }
    }

    private void log( String message )
    {
      if ( message == null ) return;

      if ( m_parserLogger != null )
      {
          m_parserLogger.logDebug( message + LINE_SEPARATOR );
      }
      else
      {
          System.out.println( message );
      }
    } // end of log method

}
